#include <iostream>
#include <utility>

#include "GLee.h"
#include <GL/glu.h>

#include "GameOverScreen.h"
#include "MyWindow.h"
#include "Button.h"
#include "MainMenu.h"
#include "TexturedEntity.h"
#include "AudioSource.h"
#include "GameOptions.h"
#include "FontManager.h"
#include "FreeTypeFont.h"

using namespace std;

GameOverScreen::GameOverScreen(MyWindow* window, const GameMode lastGameMode)
: Scene(window), m_retryBtn(NULL), m_mainMenuBtn(NULL), m_exitBtn(NULL), m_lastGameMode(lastGameMode), m_bgm(NULL)
{
}

GameOverScreen::~GameOverScreen(void)
{
}

bool GameOverScreen::init()
{
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    //Viewport[2] stores the width of the viewport, vieport[3] stores the height
    //We pass these into our font so the ortho mode can set the resolution for the window
    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);

    // Initialize the font
    FontManager* fontManager = FontManager::getInstance();
    if (fontManager->hasFont(make_pair("data/textures/ANGRY_BIRDS.ttf", 60)))
    {
        m_font = fontManager->getFont(make_pair("data/textures/ANGRY_BIRDS.ttf", 60));
    }
    else
    {
        m_font = boost::shared_ptr<FreeTypeFont>(new FreeTypeFont("data/textures/ANGRY_BIRDS.ttf",
                              viewport[2], 
                              viewport[3], 
                              60));
        fontManager->addFont(m_font);
    }

    // Initialize retry button
    m_retryBtn = new Button(boost::shared_ptr<Scene>(this));
    m_retryBtn->setDimension(Dimension(148.0f, 42.0f));
    m_retryBtn->setPosition(Vector3(viewport[2]/2.0f, 300.0f, 0.0f));
    if (!m_retryBtn->initialize()) {
        std::cerr << "Could not initialize the Retry Button" << std::endl;
        return false;
    }
    m_retryBtn->setFontSize(24);
    m_retryBtn->setLabel("RETRY ");

    // Initialize main menu button
    m_mainMenuBtn = new Button(boost::shared_ptr<Scene>(this));
    m_mainMenuBtn->setDimension(Dimension(148.0f, 42.0f));
    m_mainMenuBtn->setPosition(Vector3(viewport[2]/2.0f, 250.0f, 0.0f));
    if (!m_mainMenuBtn->initialize()) {
        std::cerr << "Could not initialize the MainMenu Button" << std::endl;
        return false;
    }
    m_mainMenuBtn->setFontSize(24);
    m_mainMenuBtn->setLabel("MAIN MENU ");

    // Initialize exit button
    m_exitBtn = new Button(boost::shared_ptr<Scene>(this));
    m_exitBtn->setDimension(Dimension(148.0f, 42.0f));
    m_exitBtn->setPosition(Vector3(viewport[2]/2.0f, 200.0f, 0.0f));
    if (!m_exitBtn->initialize()) {
        std::cerr << "Could not initialize the Exit Button" << std::endl;
        return false;
    }
    m_exitBtn->setFontSize(24);
    m_exitBtn->setLabel("EXIT ");

    // Create all entities
    createEntities();

    // Initialize the background music
    GameOptions* globalOpt = GameOptions::getOptions();
    m_bgm = new AudioSource(string("bgm_game_over"), MUSIC);
    m_bgm->setAudioFile("data/audio/game_over.ogg");
    m_bgm->setLoop(false);
    m_bgm->initialize();
    m_bgm->setVolume(globalOpt->musicLevel());
    m_bgm->play();

    return true;
}

void GameOverScreen::prepare(float dt)
{
    // Update entities
    for (EntityIterator entity = m_entities.begin(); entity != m_entities.end(); ++entity)
    {
        (*entity)->prepare(dt);
    }

    // Update buttons
    m_retryBtn->prepare(dt);
    m_mainMenuBtn->prepare(dt);
    m_exitBtn->prepare(dt);

    // Check if EXIT button has been pressed
    if (m_exitBtn->isClicked())
    {
        shutdown();
    }
    // Check if RETRY button has been pressed
    else if (m_retryBtn->isClicked())
    {
        m_nextScene = new Game(m_window, m_lastGameMode);
        m_bgm->stop();
    }
    // Check if MAIN MENU button has been pressed
    else if (m_mainMenuBtn->isClicked())
    {
        m_nextScene = new MainMenu(m_window);
        m_bgm->stop();
    }
}

void GameOverScreen::render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //Load the identity matrix (reset to the default position and orientation)
    glLoadIdentity();

    // Render entities
    for (ConstEntityIterator entity = m_entities.begin(); entity != m_entities.end(); ++entity)
    {
        (*entity)->render();
        (*entity)->postRender();
    }

    // Render title
    m_font->printString("GAME OVER", 
                        (m_screenSize.width / 2.0f) - 150.0f, 
                        (m_screenSize.height / 2.0f) + 60.0f);

    // Render buttons
    m_retryBtn->render();
    m_mainMenuBtn->render();
    m_exitBtn->render();
}

void GameOverScreen::shutdown()
{
    m_bgm->stop();
    m_nextScene = NULL;
}

void GameOverScreen::onResize(int width, int height)
{
    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho(0, width, 0, height, -1, 1);
    m_screenSize.width = static_cast<float> (width);
    m_screenSize.height = static_cast<float> (height);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

bool GameOverScreen::createEntities(void)
{
    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);

    // Create the red bird
    TexturedEntity* newEntity = new TexturedEntity(boost::shared_ptr<Scene>(this), "data/textures/levelselection1.tga");
    newEntity->setPosition(Vector3(viewport[2]/2.0f + 150.0f, 250.0f, 0.0f));
    newEntity->setPixelsSize(Dimension(70.0f, 102.0f));
    newEntity->setPositionInTexture(Vector3(625.0f, 293.0f, 0.0f));
    newEntity->setSizeInTexture(Dimension(70.0f, 102.0f));

    if (!newEntity->initialize())
    {
        delete newEntity;
        std::cerr << "Could not initialize the new RedBird entity" << std::endl;
        return false;
    }
    else
    {        
        registerEntity(newEntity);
    }

    return true;
}
